# 二、列表list
# 2.1 列表的定义格式
"""
变量名 = [元素1, 元素2,, 元素3, ...]
说明:
1. 列表以[]作为标识
2. 列表内每一个元素之间用逗号隔开

定义空列表
变量名 = []
变量名 = list()
"""
name = ["张三", "李四", "王五"]
print(f"列表元素:{name}, 列表的类型为: {type(name)}")
# 列表元素:['张三', '李四', '王五'], 列表的类型为: <class 'list'>

# 需要注意的是, 列表可以存储不同类型的数据
name = ["张三", 123, 3.14]
print(f"列表元素:{name}, 列表的类型为: {type(name)}")
# 列表元素:['张三', 123, 3.14], 列表的类型为: <class 'list'>

# 并且还支持列表嵌套
my_list = [[1,2,3], [4,5,6]]
print(f"列表元素:{my_list}, 列表的类型为: {type(my_list)}")

# 2.2 列表的下标索引
# 下标默认从0开始
# 注意: 索引超出范围会报错
# 使用列表的下标索引，打印列表的每一份元素
name = ["张三", "李四", "王五"]

for i in range(0, len(name)):
    print(name[i], end=' ')

print()

# 列表还可以反向索引(从右向左)
# 从后向前，下标从-1开始依次递减
name = ["张三", "李四", "王五"]
      #  -3     -2      -1
for i in range(-1, -len(name) - 1, -1):
    print(name[i], end=' ')

print()

# 如果列表是嵌套的列表，同同样支持下标索引。双重循环取出即可
my_list = [[1,2,3], [4,5,6]]
for i in range(0, len(my_list)):
    for j in range(0, 3):
        print(my_list[i][j], end=' ')
    print()

# 2.3 常用操作
"""
什么是方法
* 方法本质上就是函数。在Python中，如果将函数定义在类中，那么这个函数会被称为方法
* 方法和函数功能一样，有参数，也有返回值，只是使用格式不同
    函数是直接调用即可，如num = Add(5, 3)
    方法则是要先进行对象实例化，在通过“对象.方法”即可
"""

"""
方法1: 查找某元素的下标
语法: 对象.index(元素)
功能: 找到了返回该元素下标，找不到就会报错
"""
name = ["张三", "李四", "王五"]
pos = name.index("李四")
print(f"李四在列表的下标为: {pos}")
# print(f"王麻子在列表的下标为: {name.index("王麻子")}") # 不存在会报错

# 通过下标修改列表对应下标的元素值
name = ["张三", "李四", "王五"]
name[name.index("李四")] = "王麻子" # 将李四修改为王麻子
print(name)

"""
方法2: 向列表插入元素
语法: 对象.insert(下标, 元素)
功能: 在指定下标处插入指定元素
"""
id = [1, 2, 3, 4, 5, 6]
id.insert(0, 100) # 在下标为0处插入100
print(id)

"""
方法3: 追加一个元素
语法: 对象.append(元素)
功能: 尾插
"""
id = [1, 2, 3, 4, 5, 6]
id.append(666) # 尾插 666
print(id)

"""
方法4: 追加一批元素
语法: 对象.extend(其它数据容器)
功能: 尾插一批元素
"""
id = [1, 2, 3, 4, 5, 6]
language = ["c++", "python", "java"]
id.extend(language)
print(id)

"""
方法4: 删除指定下标元素
语法: del 对象[下标]  or  对象.pop(下标)
注意: pop方法还会返回删除的元素值 
"""
id = [1, 2, 3, 4, 5, 6]
del id[1] # 删除下标1的元素 -> 2
element = id.pop(0) # 删除下标0的元素 -> 1
print(f"pop方法删除的元素值是{element}, 列表: ", end="")
print(id)

"""
方法5: 删除指定元素
语法: 对象.remove(元素)
注意: 删除指定元素
"""
id = [1, 2, 3, 4, 5, 6]
id.remove(2)
print(f"删除指定元素2, 列表为:{id}")

"""
方法6: 清空列表元素
语法: 对象.clear()
"""
id = [1, 2, 3, 4, 5, 6]
print(f"原列表: {id}")
id.clear()
print(f"清空列表: {id}")

"""
方法6: 统计某元素在列表中的个数
语法: 对象.count(元素)
"""
id = [3, 2, 3, 3, 3, 6, 3, 2]
print(f"列表为: {id}, 其中3的个数为:{id.count(3)}")

"""
补充函数: 统计列表元素的个数
语法: len(列表)
"""
id = [3, 2, 3, 3, 3, 6, 3, 2]
print(f"列表为: {id}, 元素的个数为: {len(id)}")

# 2.4 遍历
# while
id = [3, 2, 3, 3, 3, 6, 3, 2]
i = 0
while i < len(id):
    print(id[i], end=' ')
    i += 1
print()
# for
for num in id: # 依次从容器中取值并赋值给num
    print(num, end=' ')


# 2.5 列表特点总结
"""
1. 可以容纳多个元素(2的63次方-1)
2. 可以容纳不同类型的元素
3. 数据是有序存储的(有下标)
4. 允许出现重复数据
5. 可以进行修改操作(增、删、差、改)
"""

# 2.6 练习1
"""
练习案例: 有一个年龄列表，内容是[21, 25, 21, 23, 22, 20]
对改列表进行如下操作
1. 定义这个列表
2. 尾插一个数字31
3. 尾插一批数字[29, 33, 30]
4. 取出第一个元素
5. 取出最后元素
6. 查找元素31，并返回它的下标
"""
age = [21, 25, 21, 23, 22, 20] # 1
age.append(31) # 2
age.extend([29, 33, 30]) # 3
element_first = age[0] # 4
element_end = age[-1]  # 5
pos_31 = age.index(31) # 6

# 2.7 练习2
"""
定义一个列表，内容是[1,2,3,4,5,6,7,8,9,10]
* 遍历列表，取出列表中的偶数，不存入新的列表中
* 使用while循环和for循环遍历新列表
"""
print()
lst1 = [1,2,3,4,5,6,7,8,9,10]
lst2 = list()
for num in lst1:
    if num % 2 == 0:
        lst2.append(num)

for num in lst2:
    print(num, end=' ')

print()
i = 0
while i < len(lst2):
    print(lst2[i], end=" ")
    i += 1